home *** CD-ROM | disk | FTP | other *** search
/ ASME's Mechanical Engine…ing Toolkit 1997 December / ASME's Mechanical Engineering Toolkit 1997 December.iso / ai / prlg195b.lzh / GAMES.LZH / TTT.PRO < prev   
Text File  |  1986-05-13  |  6KB  |  238 lines

  1.  
  2. /************************************************************************
  3. *
  4. *    programer:    Gregory L. Humphreys
  5. *
  6. *    address:    43 Longwood Drive
  7. *            Hampton, VA  23669
  8. *
  9. *    phone:        (804) 851-4550  home
  10. *            (804) 865-4534  work
  11. *
  12. *    date:        05-13-86
  13. *
  14. *    program:    Tic-Tac-Toe (TTT.PRO)
  15. *
  16. *    description:    This Prolog program plays a semi-intelligent game
  17. *            of Tic-Tac-Toe.  It lets the user go first, and it
  18. *            will try to win, block a user win, else it tries
  19. *            to pick a good move based on preset values for the
  20. *            squares.  To play the game, simply load the source
  21. *            via consult(ttt) and type go.  You will be prompted
  22. *            for a move as X, etc.  It will take the computer 
  23. *            about 4 sec. to make a move so be patient.  It is
  24. *            possible to trap the computer and win!  Good Luck!
  25. *
  26. ************************************************************************/
  27.  
  28.  
  29. /* initialize the Board, the possible Moves, and the current move Count    */
  30. /* assert them as "gamestat" and invoke rule to prompt for user input    */
  31.  
  32. go :-
  33.     Board = [[],[]],
  34.     Moves = [1,2,3,4,5,6,7,8,9],
  35.     Count is 0,
  36.     asserta (gamestat (Board, Moves, Count)),
  37.     getxmove.
  38.  
  39.  
  40. /* retrieve current "gamestat", display current board, read the X move     */
  41. /* incr. Count, check if X wins, check for a "cat" game, then get O move */
  42.  
  43. getxmove :-
  44.     gamestat ([Xmoves, Omoves], Moves1, Count1),
  45.     printboard ([Xmoves,Omoves]),
  46.     readxmove (Moves1, Moves2, Newxmove),
  47.     Count2 is Count1 + 1,
  48.     !, xwins ([Newxmove|Xmoves], [[Newxmove|Xmoves], Omoves]),
  49.     catgame (Count2, [[Newxmove|Xmoves], Omoves]),
  50.     getomove ([[Newxmove|Xmoves], Omoves], Moves2, Count2),
  51.     !, getxmove.
  52.  
  53. getxmove.    /* getxmove will always return true */
  54.  
  55.  
  56. /* prompt for and read in an X move; validate it by translating its ASCII  */
  57. /* value to the internal magic square value and check if it is a member of */
  58. /* the current set of moves, and if so then remove it from the move list   */
  59.  
  60. readxmove (Moves1, Moves2, Newxmove) :-
  61.     repeat,
  62.     print (' Enter your move > '),
  63.     get0 (Newx), nl,
  64.     trans (Newxmove, Newx),
  65.     member (Newxmove, Moves1),
  66.     remove (Newxmove, Moves1, [], Moves2).
  67.  
  68.  
  69. /* get a computer O move by returning a move that has the highest value    */
  70. /* incr. count, remove it from the move list, retract the old gamestat    */
  71. /* assert the new gamestat, display the O move                */
  72.  
  73. getomove ([Xmoves,Omoves], Moves1, Count1) :-
  74.     getomove1 ([Xmoves,Omoves], Moves1, [], Count1, Value, Newomove),
  75.     Count2 is Count1 + 1,
  76.     remove (Newomove, Moves1, [], Moves2),
  77.     retract (gamestat (_,_,_)),
  78.     asserta (gamestat ([Xmoves,[Newomove|Omoves]], Moves2,  Count2)),
  79.     trans (Newomove, Newo),
  80.     nl, print (' My move is > '),
  81.     put (Newo), nl, nl.
  82.  
  83.  
  84. /* first check to see if O can win, else get an O move (recursively)    */
  85. /* via evaluating the board with each possible move (an X win is high    */
  86. /* value), and returning the highest valued move            */
  87.  
  88. getomove1 ([Xmoves,Omoves], [First|Rest], Ext, Count1, Value1, Oout1) :-
  89.     owins ([First|Omoves], [Xmoves,[First|Omoves]]),
  90.     getomove1 ([Xmoves,Omoves], Rest, [First|Ext], Count1, Value2, Oout2),
  91.     evaluate (First, Xmoves, Value3),
  92.     maxvalue (Value3, Value2, Value1, First, Oout2, Oout1).
  93.  
  94. getomove1 (_, [], _, _, -100, []).    /* the base case which is no good */
  95.  
  96.  
  97. /* removes an element from a list */
  98.  
  99. remove (X, [], Ans, Ans).
  100.  
  101. remove (X, [X|Rest], Front, Ans) :-
  102.     remove (X, Rest, Front, Ans).
  103.  
  104. remove (X, [Y|Rest], Front, Ans) :-
  105.     remove (X, Rest, [Y|Front], Ans).
  106.  
  107. /* checks for a win for X, if so then it displays a message, etc. */
  108.  
  109. xwins (Xmoves, Board) :-
  110.     checkwin (Xmoves),
  111.     nl, printboard (Board),
  112.     nl, print (' you win '), nl,
  113.     retract (gamestat (_,_,_)),
  114.     !, fail.
  115.  
  116. xwins (_,_).
  117.  
  118.  
  119. /* checks for a win for O, if so then it displays a message, etc. */
  120.  
  121. owins (Omoves, Board) :-
  122.     checkwin (Omoves),
  123.     nl, printboard (Board),
  124.     nl, print (' I win ! '), nl,
  125.     retract (gamestat (_,_,_)),
  126.     !, fail.
  127.  
  128. owins (_,_).
  129.  
  130.  
  131. /* checks for a draw, if so then it displays a message, etc. */
  132.  
  133. catgame (9, Board) :-
  134.     nl, printboard (Board),
  135.     nl, print (' cat game '), nl,
  136.     retract (gamestat (_,_,_)),
  137.     !, fail.
  138.  
  139. catgame (_,_).
  140.  
  141.  
  142.  
  143. /* the maximum value is returned in the third param and a corresponding    */
  144. /* value is also propagated out                        */
  145.  
  146. maxvalue (Value1, Value2, Value1, Xout1, _, Xout1) :-
  147.     Value1 > Value2.
  148.  
  149. maxvalue (_, Value2, Value2, _, Xout2, Xout2).
  150.  
  151.  
  152. /* evaluates the given board returning a value */
  153.  
  154. evaluate (First, Xmoves, 50) :-
  155.     checkwin ([First|Xmoves]).    /* this has the best value */
  156.  
  157. evaluate (1, _, 1).    /* value of a side is 1 */
  158. evaluate (2, _, 2).    /* value of a corner is 2 */
  159. evaluate (3, _, 1).
  160. evaluate (4, _, 2).
  161. evaluate (5, _, 3).    /* value of the center is 3 */
  162. evaluate (6, _, 2).
  163. evaluate (7, _, 1).
  164. evaluate (8, _, 2).
  165. evaluate (9, _, 1).
  166.  
  167. evaluate (_, _, 0).
  168.  
  169.  
  170. /* checks for a win */
  171.  
  172. checkwin ([A|[B|C]]) :-
  173.     find15 (A, B, C).
  174.  
  175. /* looks for a winning combination via magic square value addition */
  176.  
  177. find15 (A, B, [C|D]) :-
  178.     (15 is A + B + C;
  179.      find15 (A, B, D);
  180.      find15 (A, C, D);
  181.      find15 (B, C, D)).
  182.  
  183.  
  184. /* displays the given board */
  185.  
  186. printboard ([Xmoves,Omoves]) :-
  187.     nl,
  188.     markrow (8, 3, 4, [Xmoves,Omoves]),
  189.     nl,
  190.     print (' ---+---+---'),
  191.     nl,
  192.     markrow (1, 5, 9, [Xmoves,Omoves]),
  193.     nl,
  194.     print (' ---+---+---'),
  195.     nl,
  196.     markrow (6, 7, 2, [Xmoves,Omoves]),
  197.     nl, nl.
  198.  
  199.  
  200. /* draws one of the three rows of the board */
  201.  
  202. markrow (A, B, C, [Xmoves,Omoves]) :-
  203.     print ('  '),
  204.     mark (A, [Xmoves,Omoves]),
  205.     print (' | '),
  206.     mark (B, [Xmoves,Omoves]),
  207.     print (' | '),
  208.     mark (C, [Xmoves,Omoves]).
  209.  
  210.  
  211. /* marks with an X or an O or a number for an open square */
  212.  
  213. mark (Z, [Xmoves,Omoves]) :-
  214.     (member (Z, Xmoves), print ('X'));
  215.     (member (Z, Omoves), print ('O'));
  216.     (trans (Z, Y), put (Y)).
  217.  
  218.  
  219. /* translates between magic square and ASCII values for each square */
  220.  
  221. trans (8, 49).
  222. trans (3, 50).
  223. trans (4, 51).
  224. trans (1, 52).
  225. trans (5, 53).
  226. trans (9, 54).
  227. trans (6, 55).
  228. trans (7, 56).
  229. trans (2, 57).
  230.  
  231.  
  232. /* finds out if an element is a member of a list */
  233.  
  234. member (Y, [Y|_]).
  235.  
  236. member (B, [_|C]) :-
  237.     member (B, C).
  238.